package com.qf.shiro.config;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.qf.shiro.user.entity.User;
import com.qf.shiro.user.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.List;

public class CustomRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
         User user = (User) principalCollection.getPrimaryPrincipal();

        //把角色信息封装到AuthorizationInfo， simpleAuthorizationInfo为其实现类
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        simpleAuthorizationInfo.addRoles(user.getRoses());

        simpleAuthorizationInfo.addStringPermissions(user.getPerms());
        return simpleAuthorizationInfo;
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获取用户名
        String username = (String) token.getPrincipal();

        //根据token中的用户提供给的身份信息，去数据库中查询该用户的密码
        User user = getUserFromDB(username);

        List<String> roles = userService.getRoles(user);

        List<String> perms = userService.getPerms(user);

        user.setRoses(roles);

        user.setPerms(perms);

        if (user==null){
            throw new UnknownAccountException("用户名不存在");
        }
        //需要把数据库中的用户的密码返回shiro
        //注意 第一个参数可以放入从数据库中查询粗来的完整的
        //的user对象,也可以指放入用户名，这里会影响后续从shiro中获取用户身份证信息
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                this.getName());

        return simpleAuthenticationInfo;
    }

    private User getUserFromDB(String username) {

        return   userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername,username));


    }
}
